package ils.services;


import ils.domain.catalog.model.Book;
import ils.domain.catalog.model.BookRepository;
import ils.domain.catalog.model.Category;
import ils.domain.catalog.model.CategoryRepository;
import ils.util.HibernateSession;
import ils.util.HibernateSessionManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Collections;
import java.util.List;
import java.util.Map;

public class CatalogServiceImpl implements CatalogService
{
    private static final Logger logger = LoggerFactory.getLogger(CatalogServiceImpl.class);
    private BookRepository bookRepository;
    private CategoryRepository categoryRepository;
    private HibernateSessionManager hibernateSessionManager;
    
    @Override
    public Book addBook(Book book)
    {
        try(HibernateSession session = hibernateSessionManager.getSession())
        {
            return bookRepository.createBook(book);
        }
    }

    public void setBookRepository(BookRepository bookRepository)
    {
        this.bookRepository = bookRepository;
    }

    @Override
    public Category createCategory(String categoryName, Integer parentId)
    {
        try(HibernateSession session = hibernateSessionManager.getSession())
        {
            Category category = new Category();
            category.setName(categoryName);
            if(parentId != null)
            {
                Category parent = categoryRepository.getCategory(parentId);
                String parentFullName = parent.getFullName();
                String fullName = parentFullName + "/" + categoryName;
                category.setFullName(fullName);
                category.setParentId(parentId);
            }else
            {
                category.setFullName("/" + categoryName);
            }
            return categoryRepository.createCetegory(category);
        }
    }

    public void setCategoryRepository(CategoryRepository categoryRepository)
    {
        this.categoryRepository = categoryRepository;
    }

    @Override
    public List<Book> getBooksInCategory(boolean includeSubCategories, int categoryId) {
        try(HibernateSession session = hibernateSessionManager.getSession())
        {
            return bookRepository.getBooksInCategory(includeSubCategories, categoryId);
        }
    }

    @Override
    public List<Book> getBooksInCategory(String categoryName, boolean includeSubCategories) {
        try(HibernateSession session = hibernateSessionManager.getSession())
        {
            Category category = categoryRepository.findCategory(categoryName);
            return getBooksInCategory(includeSubCategories, category.getId());
        }
    }

    @Override
    public List<Category> getSubCategories(Integer id) {
        try(HibernateSession session = hibernateSessionManager.getSession())
        {
            List<Category> categories = categoryRepository.getDescendants(id);
            Collections.sort(categories);
            return categories;
        }
    }

    @Override
    public List<Book> searchBooks(String type, String term) {
        try(HibernateSession session = hibernateSessionManager.getSession())
        {
            return bookRepository.searchBooks(term, type);
        }
    }

    @Override
    public Map<Integer, Book> getBooks(List<Integer> bookIds) {
        try(HibernateSession session = hibernateSessionManager.getSession())
        {
            return bookRepository.getBooks(bookIds);
        }
    }

    public void setHibernateSessionManager(HibernateSessionManager hibernateSessionManager) {
        this.hibernateSessionManager = hibernateSessionManager;
    }
}
